// #ifdef APP-PLUS
import database from './SQLite.js'
// #endif

// #ifdef H5
import database from './webSQL.js'
// #endif

function getCreateSql(tableName, type) {
    let typeSqlArr = []
    for (let key in type) {
        typeSqlArr.push(`"${key}" ${type[key]}`)
    }
    let typeSql = typeSqlArr.join()
    return `CREATE TABLE if not exists ${tableName}(${typeSql})`
}

function getInsertSql(tableName, arr) {
    let keyArr = []
    let valuesArr = []
    arr.forEach((obj, i) => {
        let valueArr = []
        for (let key in obj) {
            if (i === 0) {
                keyArr.push(key)
            }
            if (typeof obj[key] === "string") {
                valueArr.push('"' + obj[key] + '"')
            } else {
                valueArr.push(obj[key])
            }
        }
        valuesArr[i] = "(" + valueArr.join() + ")"
    })
    let keys = keyArr.join()
    let values = valuesArr.join()
    return `insert into ${tableName}(${keys}) values${values}`
}

function getDeleteSql(obj) {
    let whereArr = obj.where
    let sql = `delete from ${obj.from}`
    if (Array.isArray(whereArr) && whereArr.length) {
        sql = `${sql} where ${getWhereSql(whereArr)}`
    }
    return sql
}

function getUpdateSql(obj) {
    let whereArr = obj.where
    let sql = `update ${obj.from}`
    let setObj = obj.set
    if (Object.prototype.toString.call(setObj) === '[object Object]' && Object.keys(setObj)) {
        sql = `${sql} set ${getSetSql(setObj)}`
    }
    if (Array.isArray(whereArr) && whereArr.length) {
        sql = `${sql} where ${getWhereSql(whereArr)}`
    }
    return sql
}

function getSelectSql(obj) {
    let selectSql = (Array.isArray(obj.select) && obj.select.length) ? obj.select.join() : '*'
    let sql = `select ${selectSql} from ${obj.from}`
    let whereArr = obj.where
    if (Array.isArray(whereArr) && whereArr.length) {
        sql = `${sql} where ${getWhereSql(whereArr)}`
    }
    let orderObj = obj.order
    if (Object.prototype.toString.call(orderObj) === '[object Object]' && Object.keys(orderObj)) {
        sql = `${sql} order by ${getOrderSql(orderObj)}`
    }
    if (typeof obj.limit === 'number') {
        sql = `${sql} limit ${obj.limit}`
    }
    if (typeof obj.offset === 'number') {
        sql = `${sql} offset ${obj.offset}`
    }
    return sql
}

function getWhereSql(whereArr) {
    return whereArr.filter(item => {
        return Object.prototype.toString.call(item) === '[object Object]' && Object.keys(item)
    }).map(item => {
        let andSql = []
        for (let key in item) {
            andSql.push(key + ' ' + item[key])
        }
        return andSql.join(' and ')
    }).join(' or ')
}

function getSetSql(setObj) {
    let setArr = []
    for (let key in setObj) {
        if (typeof setObj[key] === "string") {
            setArr.push(`${key}="${setObj[key]}"`)
        } else {
            setArr.push(`${key}=${setObj[key]}`)
        }
    }
    return setArr.join()
}

function getOrderSql(orderObj) {
    let arr = []
    for (let key in orderObj) {
        let descFlag = (typeof orderObj[key] === 'string') && (orderObj[key].toLowerCase() === 'desc')
        arr.push(key + ' ' + (descFlag ? 'desc' : ''))
    }
    return arr.join()
}

function init(dbName, arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) {
            reject('请传入数组')
        }
        let sqlArr = arr.map(item => getCreateSql(item[0], item[1]))
        database.execute(dbName, sqlArr).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function insert(dbName, tableName, arr) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(arr)) { // 如果只插入一条数据，可只传入一个对象
            arr = [arr]
        }
        let sql = getInsertSql(tableName, arr)
        database.execute(dbName, sql).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function myDelete(dbName, obj) {
    return new Promise((resolve, reject) => {
        let sql = getDeleteSql(obj)
        database.execute(dbName, sql).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function update(dbName, obj) {
    return new Promise((resolve, reject) => {
        let sql = getUpdateSql(obj)
        database.execute(dbName, sql).then(res => {
            resolve(res)
        }).catch(err => {
            reject(err)
        })
    })
}

function select(dbName, obj, pageParams) {
    return new Promise((resolve, reject) => {
        if (pageParams) {
            let sql1 = getSelectSql({
                ...obj,
                limit: pageParams.size,
                offset: (pageParams.current - 1) * pageParams.size + pageParams.offset
            })
            let sql2 = getSelectSql({
                select: ['count(*)'],
                from: obj.from,
                where: obj.where
            })

            Promise.all([database.select(dbName, sql1), database.select(dbName, sql2)]).then(res => {
                resolve({
                    data: [...res[0]], // websql 这里返回的是伪数组
                    total: res[1][0]['count(*)']
                })
            }).catch(err => {
                reject(err)
            })
        } else {
            let sql = getSelectSql(obj)
            database.select(dbName, sql).then(res => {
                resolve([...res]) // websql 这里返回的是伪数组
            }).catch(err => {
                reject(err)
            })
        }
    })
}

let useDatabase = {
    init,
    insert,
    delete: myDelete,
    update,
    select
}

export default useDatabase
